package com.fatsatsuma.email;

import java.io.StringWriter;
import java.util.Properties;

import org.apache.log4j.Logger;

import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;

/**
 * @author $Id: VelocityTemplateHandler.java,v 1.3 2006/11/28 17:32:32 gevans
 *         Exp $
 */
public class VelocityTemplateHandler extends AbstractTemplateHandler implements ITemplateHandler {

	private Logger log = Logger.getLogger(this.getClass());

	private IEmailTemplate template;

	private VelocityEngine engine = null;

	public VelocityTemplateHandler() {
		engine = new VelocityEngine();
		try {
			engine.init(new Properties());
		} catch (Exception exp) {
			log.error("Unable to initialize velocity engine", exp);
		}
	}

	public void setTemplate(IEmailTemplate template) {
		this.template = template;
	}

	public IEmail generateEmail(IContext context) {

		if (log.isDebugEnabled()) {
			log.debug("Using Engine   : " + engine);
			log.debug("Using Context  : " + context);
			log.debug("Using Template : " + template);
		}

		Email email = new Email();

		email.setTemplate(this.template);

		// lets set the important bits

		if (log.isDebugEnabled()) {
			log.debug("Setting To Address...");
		}

		email.setTo(convertToInternetAddresses(template.getToAddresses(), context));

		if (log.isDebugEnabled()) {
			log.debug("Setting Cc Address...");
		}

		email.setCc(convertToInternetAddresses(template.getCcAddresses(), context));

		if (log.isDebugEnabled()) {
			log.debug("Setting Bcc Address...");
		}

		email.setBcc(convertToInternetAddresses(template.getBccAddresses(), context));

		if (log.isDebugEnabled()) {
			log.debug("Setting From Address...");
		}

		try {
			email.setFrom(getAddressFromString(template.getFrom(), context));
		} catch (Exception exp) {
		}

		if (log.isDebugEnabled()) {
			log.debug("Setting Subject...");
		}

		email.setSubject(evaluateString(template.getSubject(), context));

		if (log.isDebugEnabled()) {
			log.debug("Before Evaluation... " + template.getBodyText());
		}
		String text = evaluateString(template.getBodyText(), context);
		if (log.isDebugEnabled()) {
			log.debug("Setting Body Text... " + text);
		}
		email.setBodyText(text);
		if (log.isDebugEnabled()) {
			log.debug("Before Evaluation... " + template.getBodyHtml());
		}
		String html = evaluateString(template.getBodyHtml(), context);
		if (log.isDebugEnabled()) {
			log.debug("Setting Body HTML... " + html);
		}
		email.setBodyHtml(html);

		if (log.isDebugEnabled()) {
			log.debug("Email Generation Complete");
		}

		email.setContentType(template.getContentType());

		if (log.isDebugEnabled()) {
			log.debug("Email Generation Complete");
		}

		email.setImageBasePath(template.getImageBasePath());
		email.setShouldEmbedImages(template.isShouldEmbedImages());
		return email;
	}

	public IContext getContext() {
		IContext context = new VelocityContext();
		context.setParameter("utils", new VelocityStringUtilities());
		return context;
	}

	protected String evaluateString(String input, IContext context) {
		Context parameters = context.getContext();

		StringWriter textWriter = new StringWriter();
		try {
			engine.evaluate(parameters, textWriter, template.getName(), input);
		} catch (Exception exp) {
			log.error("Unable to parse string", exp);
		}
		return textWriter.toString();
	}

}
